package com.forum.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.forum.common.constant.ErrorCodeEnum;
import com.forum.common.utils.R;
import com.forum.user.entity.ForumUser;
import com.forum.user.mapper.ForumUserMapper;
import com.forum.user.service.ForumUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.forum.user.utils.JWTUtils;
import com.forum.user.vo.UpdateUserPasswordVo;
import com.forum.user.vo.UserVo;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;


import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author bncgnc
 * @since 2022-01-04
 */
@Service
public class ForumUserServiceImpl extends ServiceImpl<ForumUserMapper, ForumUser> implements ForumUserService {
    @Autowired
    private ForumUserMapper forumUserMapper;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    //密码加密盐，组员名字拼音缩写
    private final String passwordSlat = "zhoumindaxuepanwenliangjianingcaiyuanling";

    /**
     * 根据用户名称查找用户
     * @param forumUser
     * @return
     */
    @Override
    public R findUserByName(ForumUser forumUser) {
        Page page = new Page(1,10);
        QueryWrapper<ForumUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("userName",forumUser.getUserName());
        forumUserMapper.selectPage(page,queryWrapper);
        List<ForumUser>forumUserList=page.getRecords();
        return R.ok().put("userList",forumUserList).put("success","ok");
    }

    @Override
    public R register(ForumUser forumUser) {
        /**
         * 1.判断参数是否合法
         * 2.判断账户是否存在
         * 3.如果账户不存在，注册账户
         * 4.生成token
         * 5.纯如redis，并返回成功结果
         * 6.将上述功能加入事务，一但中间过程出现任何问题，执行回滚
         */

        R r =new R();
        String userName= forumUser.getUserName();
        String userEmail=forumUser.getUserEmail();
        String userPhonenum=forumUser.getUserPhonenum();
        String userNickname=forumUser.getUserNickname();
        String password=forumUser.getPassword();

        if (StringUtils.isBlank(userName)
                ||StringUtils.isBlank(userNickname)
                ||StringUtils.isBlank(password)){
            return R.error(ErrorCodeEnum.VALID_EXCEPTION.getCode(),ErrorCodeEnum.VALID_EXCEPTION.getMessage());         }


        //用户名唯一，昵称可重复
        LambdaQueryWrapper<ForumUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ForumUser::getUserName,userName);
        forumUser = forumUserMapper.selectOne(queryWrapper);

        //判断用户名是否重复
        if (forumUser!=null){
            return R.error(ErrorCodeEnum.VALID_EXCEPTION.getCode(),ErrorCodeEnum.VALID_EXCEPTION.getMessage());         }

        forumUser=new ForumUser();
        forumUser.setUserName(userName);
        forumUser.setUserName(userEmail);
        forumUser.setUserPhonenum(userPhonenum);
        forumUser.setUserNickname(userNickname);
        forumUser.setPassword(DigestUtils.md5Hex(password+passwordSlat));
        forumUser.setUserLastloginTime(new Date());
        forumUser.setCreateTime(new Date());
        forumUser.setUserStatus(forumUser.getUserStatus());
        //id？
        this.forumUserMapper.insert(forumUser);
        //生成token
        String token = JWTUtils.createToken(forumUser.getId());
        redisTemplate.opsForValue().set("TOKEN_"+token, JSON.toJSONString(forumUser),1, TimeUnit.DAYS);

        Long id =forumUser.getId();
        //注册成功
        return R.ok().put("data",token).put("success" , true).put("id",id);
    }

    @Override
    public R login(UserVo userVo) {
        /**
         * 1、检查参数是否合法
         * 2、根据name和password查询登录用户是否在forum_user表
         * 3、如果不存在，登陆失败；如果存在，使用jwt生成token，返回给前端
         * 3.5、验证码 uuid=captcha
         * 4、token存入redis，认证是否登录时，先认证token字符串是否合法，再前往redis确认token是否存在；若存在则放行，若不存在，报token错误
         */

        String name =userVo.getUsername();
        String password = userVo.getPassword();
        R r = new R();

        //1、检查参数是否合法
        if(StringUtils.isBlank(name)||StringUtils.isBlank(password)){
            return R.error(ErrorCodeEnum.VALID_EXCEPTION.getCode(),ErrorCodeEnum.VALID_EXCEPTION.getMessage());
        }
        System.out.println("name:"+name);
        System.out.println("密码:"+password);
        //对密码进行加密，使用md5Hex,注册时也应该对用户密码使用加密
        password= DigestUtils.md5Hex(password+passwordSlat);

        //2、根据id和password查询登录用户是否在forum_user表
        LambdaQueryWrapper<ForumUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ForumUser::getUserName,name);
        queryWrapper.eq(ForumUser::getPassword,password);
        queryWrapper.select(ForumUser::getId,ForumUser::getUserName,ForumUser::getRoleId);
        ForumUser  forumUser = forumUserMapper.selectOne(queryWrapper);

        //3、如果不存在，登陆失败；如果存在，使用jwt生成token，返回给前端
        if (forumUser==null){
            return  R.error(ErrorCodeEnum.VALID_EXCEPTION.getCode(),ErrorCodeEnum.VALID_EXCEPTION.getMessage());        }
        //3.5验证码校验
        if ( !userVo.getUuid().equals(userVo.getCaptcha()) ){
            return  R.error(ErrorCodeEnum.VALID_EXCEPTION.getCode(),ErrorCodeEnum.VALID_EXCEPTION.getMessage());        }


        //3、1 生成token
        String token = JWTUtils.createToken(forumUser.getId());
        redisTemplate.opsForValue().set("TOKEN_"+token, JSON.toJSONString(forumUser),1, TimeUnit.DAYS);
        //3.2设置登录时间
        forumUser.setUserLastloginTime(new Date());
        System.out.println("用户登录成功");
        Long id=forumUser.getId();
        return R.ok().put("data",token).put("success",true).put("id",id);
    }

    @Override
    public R logout(String token) {
        redisTemplate.delete("TOKEN_"+token);
        R r = new R();
        return R.ok().put("success",true);
    }

    @Override
    public ForumUser checkToken(String token) {
        //1.判空
        if (StringUtils.isBlank(token)){
            return null;
        }
//        System.out.println("你好你好");
        //2.使用JWT自带的checkToken方法检测token是否合法
        Map<String,Object> stringObjectMap = JWTUtils.checkToken(token);
        if (stringObjectMap==null){
            return null;
        }
        //3.查找token是否在redis中
        String userJson = redisTemplate.opsForValue().get("TOKEN_"+token);
//        System.out.println("userJson + " + userJson);
        if(StringUtils.isBlank(userJson)){
            return null;
        }
        ForumUser forumUser =JSON.parseObject(userJson,ForumUser.class);
        System.out.println("用户登录状态校验成功");
        return forumUser;
    }

    /**
     * 用户管理员查看所有的普通用户的信息
     * @param forumUser
     * @return
     */
    @Override
    public R listAllCommonUser(ForumUser forumUser) {
        /**
         * 1.判断是否为管理员用户，如果不是，返回权限不足
         * 2、如果是管理员用户，则查询全部普通用户
         */
        //* 1.判断是否为管理员用户，如果不是，返回权限不足,用户管理员的roleId为0
        if (forumUser.getRoleId()!=0){
            return R.error(ErrorCodeEnum.NO_AUTHENTICATION.getCode(),ErrorCodeEnum.NO_AUTHENTICATION.getMessage());
        }
        //2、分页查询
        Page<ForumUser>page = new Page<>(1,10);
        QueryWrapper<ForumUser>queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("roleId",1);
        queryWrapper.select("id","userName","userNickname","roleId");

        Page<ForumUser> userPage = forumUserMapper.selectPage(page, queryWrapper);
        List<ForumUser> records = userPage.getRecords();
        return R.ok().put("success",true).put("records",records);
    }

    /**
     * 普通用户更新自己的基本信息
     * @param forumUser
     * @return
     */
    @Override
    public R updateUserBase(ForumUser forumUser) {
        /**
         * 1、所有值不能为空值
         * 2、开始修改值
         * 3、根据id进行修改
         */
        if (forumUser.getUserNickname()==null||forumUser.getUserEmail()==null||forumUser.getUserPhonenum()==null){
            return R.error(ErrorCodeEnum.VALID_EXCEPTION.getCode(),ErrorCodeEnum.VALID_EXCEPTION.getMessage());
        }
        QueryWrapper<ForumUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",forumUser.getId());
        forumUserMapper.update(forumUser,queryWrapper);

        return R.ok().put("success",true);
    }

    @Override
    public R updateUserPassword(UpdateUserPasswordVo updateUserPasswordVo) {
        /**
         * 1、判断前端传过来的密码是否正确
         * 2、更新
         */
        Long id = updateUserPasswordVo.getId();
        //1、判断前端传过来的密码是否正确
        String password = forumUserMapper.selectById(id).getPassword();
        if (updateUserPasswordVo.getOldPassword()!=password){
            return R.error(ErrorCodeEnum.VALID_EXCEPTION.getCode(),ErrorCodeEnum.VALID_EXCEPTION.getMessage());
        }
        //2、更新
        ForumUser forumUser =new ForumUser();
        forumUser.setId(updateUserPasswordVo.getId());
        forumUser.setPassword(updateUserPasswordVo.getNewPassword());
        forumUserMapper.updateById(forumUser);
        return R.ok().put("success",true).put("id",id);


    }

    /**
     * 根据id直接删
     * @param id
     * @return
     */
    @Override
    public R deleteUser(Long id) {
        forumUserMapper.deleteById(id);
        return R.ok().put("success",true);
    }
}
